package fm.service.impl;

import com.alibaba.fastjson.JSON;
import fm.dao.HibernateBaseDao;
import fm.entity.*;
import fm.entityEnum.Carrier;
import fm.entityEnum.ExchangeStatus;
import fm.entityEnum.ShareTypeEnum;
import fm.exception.BizException;
import fm.service.ActivityService;
import fm.util.CommonUtils;
import fm.util.MathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类名：fm.servcie.impl.ActivityServiceImpl
 * 创建者： CM .
 * 创建时间：2016/3/10
 */
@Service("activityService")
public class ActivityServiceImpl implements ActivityService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ActivityServiceImpl.class);
    @Autowired
    private HibernateBaseDao baseDao;

    /**
     * 以ID索引获得活动信息
     *
     * @param id
     * @return
     */
    public Activity getById(Long id) {
        return (Activity) baseDao.getById(Activity.class, id);
    }

    /**
     * 根据活动id获取参与列表
     *
     * @param activity
     * @return
     */
    public List<RecorderParticipation> getRecorderParticipationsByActivityId(Activity activity) {
        String hql = "from RecorderParticipation rp where rp.activity=? order by rp.createTime ";
        List<RecorderParticipation> recorderParticipations = (List<RecorderParticipation>) baseDao.pageQuery(hql, 0, 10, activity);
        return recorderParticipations;
    }

    /**
     * 用户是否参与过活动
     *
     * @param user
     * @param activity
     * @return
     */
    public List<RecorderParticipation> getUserRecorders(WxUser user, Activity activity) {
        String hql = "from RecorderParticipation rp where rp.wxUser=? and rp.activity=?";
        List recorders = baseDao.queryForList(hql, user, activity);
        return recorders;
    }

    /**
     * 根据运营商获取该活动配置的流量包
     *
     * @param activity
     * @param carrier
     * @return
     */
    public List<ActivityFlow> getActivityFlows(Activity activity, Carrier carrier) {
        String hql = "from ActivityFlow af where af.activity=? and af.flow.carrier=?";
        List activityFlows = baseDao.queryForList(hql, activity, carrier);
        return activityFlows;
    }

    /**
     * 抽取奖品
     *
     * @param activityFlows
     * @return
     * @throws BizException
     */
    public ActivityFlow getPrize(List<ActivityFlow> activityFlows) throws BizException {
        List<Double> probableList = new ArrayList();
        for (int i = 0; i < activityFlows.size(); i++) {
            double currentP = activityFlows.get(0).getProbability();
            for (int j = i; j > 0; j--) {
                currentP = currentP + activityFlows.get(j).getProbability();
            }
            probableList.add(currentP);
        }

        double result = MathUtils.randomInRange(probableList.get(probableList.size() - 1));
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("sum the pb :{} ,random result: {}", probableList.get(probableList.size() - 1), result);
        }
        for (int i = 0; i < probableList.size(); i++) {
            if (probableList.get(i) >= result) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("当前范围： {} - {} ,对应流量包 ：{}",
                            (i <= 0 ? 0.0 : probableList.get(i - 1)), probableList.get(i),
                            JSON.toJSONString(activityFlows.get(i).getFlow()));
                }
                return activityFlows.get(i);
            }
        }
        throw new BizException("获奖比例错误，无法抽取随机数！");
    }


    /**
     * 获取活动的中奖人列表 默认5人
     *
     * @param activity
     * @return
     */
    public List getWinnerList(Activity activity) {
        List<RecorderParticipation> recorders = getRecorderParticipationsByActivityId(activity);
        List<Map> rs = new ArrayList();
        DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        for (RecorderParticipation recorder : recorders) {
            Map<String, Object> r = new HashMap();
            r.put("name", recorder.getWxUser().getNickname());
            r.put("tel", recorder.getTelephone().substring(0, 4) + "****" + recorder.getTelephone().substring(7, 11));
            r.put("time", sdf.format(recorder.getCreateTime()));
            r.put("prize", recorder.getFlow().getCapacity() + "M");
            r.put("avatar", recorder.getWxUser().getHeadimgurl());
            rs.add(r);
        }
        return rs;
    }

    /**
     * 添加中奖纪录
     *
     * @param prize
     * @param activity
     * @param user
     * @param isWinner
     * @param tel
     */
    public RecorderParticipation addRecorder(Flow prize, Activity activity, WxUser user, boolean isWinner, String tel) {
        RecorderParticipation recorderParticipation = new RecorderParticipation();
        if (!CommonUtils.isEmpty(prize)) {
            recorderParticipation.setFlow(prize);
        }
        recorderParticipation.setCreateTime(new Timestamp(System.currentTimeMillis()));
        recorderParticipation.setExchangeStatus(ExchangeStatus.NOEXCHANGE);
        recorderParticipation.setWxUser(user);
        recorderParticipation.setWinning(new Byte(isWinner ? "1" : "0"));
        recorderParticipation.setTelephone(tel);
        //更新奖品剩余数量
        activity.setRemainCount(activity.getRemainCount() - 1);
        updateActivity(activity);
        recorderParticipation.setActivity(activity);
        baseDao.save(recorderParticipation);

        LOGGER.info("user:{} recorder create,is winner:{},flow package :{}", user.getNickname(), isWinner, CommonUtils.isEmpty(prize) ? "null" : prize.getId());
        return recorderParticipation;
    }

    @Override
    public Activity updateActivity(Activity activity) {
        baseDao.update(activity);
        return (Activity) baseDao.getById(Activity.class, activity.getId());
    }

    @Override
    public ShareConfig getShareConfigBuyUser(WxUser user) {
        String hql = "from ShareConfig sc where sc.wxUser=?";
        return (ShareConfig) baseDao.getUnique(hql, user);
    }

    @Override
    public Long addShareConfig(ShareConfig config) {
        String hql = "from ShareConfig sc where sc.wxUser=?";
        ShareConfig sc = (ShareConfig) baseDao.getUnique(hql, config.getWxUser());
        if (!CommonUtils.isEmpty(sc)) {
            //已经存在的，修改
            sc.setShareType(config.getShareType());
            if (ShareTypeEnum.LINK.equals(config.getShareType())) {
                sc.setDownloadLink(config.getDownloadLink());
            } else {
                sc.setTdCode(config.getTdCode());
            }
            baseDao.update(sc);
        } else {
            baseDao.save(config);
        }
        return config.getId();
    }
}
